package com.rfid.sockethelper;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.provider.OpenableColumns;
import android.text.TextUtils;

import com.rfid.DirectoryBean;
import com.rfid.event.SendStatus;
import com.rfid.util.FileUtil;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;

public class Base {

    /**采用全局静态线程池方式，后续版本再完整替代。*/
    protected static Executor mPubExecutor = Executors.newCachedThreadPool();
    private OutputStream mOutputStream = null;
    protected String ip;
    private Lock mLock;
    protected void init(OutputStream outputStream, String ip, Lock lock) {
        this.mOutputStream = outputStream;
        this.ip = ip;
        this.mLock = lock;
    }

    public void setRemoteIp(String ip) {
        this.ip = ip;
    }

    public String getRemoteIp() {
        return ip;
    }

    public void sendFile(final Context context, final Uri uri) {
        if (mOutputStream == null) {
            EventBus.getDefault().post(new SendStatus(1,IOHelper.CMD_SEND_FILE,ip));
            return;
        }
        mPubExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    mLock.lock();
                    String path = getPath(context, uri);
                    boolean r = IOHelper.sendFile(mOutputStream, path);
                    EventBus.getDefault().post(new SendStatus(r?0:2,IOHelper.CMD_SEND_FILE,ip));
                } catch (Exception e) {
                    EventBus.getDefault().post(new SendStatus(2,IOHelper.CMD_SEND_FILE,ip));
                } finally {
                    mLock.unlock();
                }
            }
        });
    }

    protected void sendFile(final String path) {
        if (mOutputStream == null) {
            EventBus.getDefault().post(new SendStatus(1,IOHelper.CMD_SEND_FILE,ip));
            return;
        }
        mPubExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    File file = new File(path);
                    if (!file.exists()) {
                        EventBus.getDefault().post(new SendStatus(3,IOHelper.CMD_SEND_FILE,ip));
                        return;
                    }
                    mLock.lock();
                    boolean r = IOHelper.sendFile(mOutputStream, path);
                    EventBus.getDefault().post(new SendStatus(r?0:2,IOHelper.CMD_SEND_FILE,ip));
                } catch (Exception e) {
                    EventBus.getDefault().post(new SendStatus(2,IOHelper.CMD_SEND_FILE,ip));
                } finally {
                    mLock.unlock();
                }
            }
        });
    }

    public void sendQueryFileListCmd(final String path) {
        System.out.println("sendQueryFileListCmd path = " + path);
        if (mOutputStream == null) {
            EventBus.getDefault().post(new SendStatus(1,IOHelper.CMD_REQ_FILE_LIST,ip));
            return;
        }
        System.out.println("base sendQueryFileListCmd");
        mPubExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    mLock.lock();
                    IOHelper.sendQueryFileList(mOutputStream,path);
                    EventBus.getDefault().post(new SendStatus(0,IOHelper.CMD_REQ_FILE_LIST,ip));
                } catch (Exception e) {
                    e.printStackTrace();
                    EventBus.getDefault().post(new SendStatus(2,IOHelper.CMD_REQ_FILE_LIST,ip));
                } finally {
                    mLock.unlock();
                }
            }
        });
    }

    public void sendFileListInfo(final DirectoryBean bean) {
        if (mOutputStream == null) {
            EventBus.getDefault().post(new SendStatus(1,IOHelper.CMD_SEND_FILE_LIST,ip));
            return;
        }
        mPubExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    mLock.lock();
                    IOHelper.sendFileList(mOutputStream,bean);
                    EventBus.getDefault().post(new SendStatus(0,IOHelper.CMD_SEND_FILE_LIST,ip));
                } catch (Exception e) {
                    e.printStackTrace();
                    EventBus.getDefault().post(new SendStatus(2,IOHelper.CMD_SEND_FILE_LIST,ip));
                } finally {
                    mLock.unlock();
                }
            }
        });
    }

    public void sendReqFileCmd(final String path) {
        if (mOutputStream == null) {
            EventBus.getDefault().post(new SendStatus(1,IOHelper.CMD_REQ_FILE,ip));
            return;
        }
        mPubExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    mLock.lock();
                    IOHelper.sendReqFileCmd(mOutputStream,path);
                    EventBus.getDefault().post(new SendStatus(0,IOHelper.CMD_REQ_FILE,ip));
                } catch (Exception e) {
                    e.printStackTrace();
                    EventBus.getDefault().post(new SendStatus(2,IOHelper.CMD_REQ_FILE,ip));
                } finally {
                    mLock.unlock();
                }
            }
        });
    }

    public void sendFileToPath(final String path, final String rpath) {
        if (mOutputStream == null) {
            EventBus.getDefault().post(new SendStatus(1,IOHelper.CMD_SET_FILE,ip));
            return;
        }
        mPubExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    mLock.lock();
                    IOHelper.sendSetFile(mOutputStream,path,rpath);
                    EventBus.getDefault().post(new SendStatus(0,IOHelper.CMD_SET_FILE,ip));
                } catch (Exception e) {
                    e.printStackTrace();
                    EventBus.getDefault().post(new SendStatus(2,IOHelper.CMD_SET_FILE,ip));
                } finally {
                    mLock.unlock();
                }
            }
        });
    }

    public void sendFileToPath(final Context context, final Uri uri,String rpath) {
        if (mOutputStream == null) {
            EventBus.getDefault().post(new SendStatus(1,IOHelper.CMD_SET_FILE,ip));
            return;
        }
        try {
            String path = getPath(context, uri);
            System.out.println("sendFileToPath local path = " + path);
            sendFileToPath(path,rpath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sendDeleteFile(final String path) {
        if (mOutputStream == null) {
            EventBus.getDefault().post(new SendStatus(1,IOHelper.CMD_DELETE_FILE,ip));
            return;
        }
        mPubExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    mLock.lock();
                    IOHelper.sendDeleteFile(mOutputStream,path);
                    EventBus.getDefault().post(new SendStatus(0,IOHelper.CMD_DELETE_FILE,ip));
                } catch (Exception e) {
                    e.printStackTrace();
                    EventBus.getDefault().post(new SendStatus(2,IOHelper.CMD_DELETE_FILE,ip));
                } finally {
                    mLock.unlock();
                }
            }
        });
    }

    private String getPath(Context context, Uri uri) throws IOException {
        String path = uri.getPath();
        path = path.replace("external_files", "sdcard").replace(":", "").replace("：", "");
        File file = new File(path);
        if (!file.exists()) {
            String fname = getName(context,uri);
            File tpf = new File("/sdcard/" + Environment.DIRECTORY_DOWNLOADS, TextUtils.isEmpty(fname)?file.getName():fname);
            InputStream in = context.getContentResolver().openInputStream(uri);
            FileUtil.streamToFile(in, tpf);
            path = tpf.getPath();
        }
        return path;
    }

    private String getName(Context context,Uri uri) {
        Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
        if (cursor != null && cursor.moveToFirst()) {
            int displayNameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
            if (!cursor.isNull(displayNameIndex)) {
                String fileName = cursor.getString(displayNameIndex);
                return fileName;
            }
        }
        return null;
    }

    public void send(final String text) {
        if (mOutputStream == null) {
            EventBus.getDefault().post(new SendStatus(1,IOHelper.CMD_SET_FILE,ip));
            return;
        }
        mPubExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    mLock.lock();
                    IOHelper.writeText(mOutputStream, text);
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    mLock.unlock();
                }
            }
        });

    }

    //========================start 刷脸开门配置程序专用===================================
    /**请求某个配置文件内容*/
    public void sendConfigReq(final String name) {
        if (mOutputStream == null) {
            return;
        }
        System.out.println("sendConfigReq");
        mPubExecutor.execute(new Runnable() {
            @Override
            public void run() {
                if (mOutputStream == null) {
                    return;
                }
                try {
                    mLock.lock();
                    IOHelper.queryConfig(mOutputStream,name);
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    mLock.unlock();
                }
            }
        });
    }
    /**请求配置文件列表*/
    public void sendConfigsReq() {
        if (mOutputStream == null) {
            EventBus.getDefault().post(new SendStatus(1,IOHelper.CMD_QUERY_CONFIGS,ip));
            return;
        }
        System.out.println("sendConfigsReq");
        mPubExecutor.execute(new Runnable() {
            @Override
            public void run() {
                if (mOutputStream == null) {
                    return;
                }
                try {
                    mLock.lock();
                    IOHelper.queryConfigNames(mOutputStream);
                    EventBus.getDefault().post(new SendStatus(0,IOHelper.CMD_QUERY_CONFIGS,ip));
                } catch (IOException e) {
                    e.printStackTrace();
                    EventBus.getDefault().post(new SendStatus(2,IOHelper.CMD_QUERY_CONFIGS,ip));
                } finally {
                    mLock.unlock();
                }
            }
        });
    }
    /**发送配置文件列表*/
    public void sendConfigNames(final String text) {
        if (mOutputStream == null) {
            EventBus.getDefault().post(new SendStatus(1,IOHelper.CMD_RESPON_CONFIGS,ip));
            return;
        }
        mPubExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    mLock.lock();
                    IOHelper.sendConfigNames(mOutputStream,text);
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    mLock.unlock();
                }
            }
        });
    }

    /**发送配置文件内容*/
    public void sendConfig(final String name, final String text) {
        if (mOutputStream == null) {
            EventBus.getDefault().post(new SendStatus(1,IOHelper.CMD_SET_CONFIG,ip));
            return;
        }
        mPubExecutor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    mLock.lock();
                    IOHelper.writeConfig(mOutputStream,name,text);
                    EventBus.getDefault().post(new SendStatus(0,IOHelper.CMD_SET_CONFIG,ip));
                } catch (IOException e) {
                    e.printStackTrace();
                    EventBus.getDefault().post(new SendStatus(2,IOHelper.CMD_SET_CONFIG,ip));
                } finally {
                    mLock.unlock();
                }
            }
        });
    }

    //==============================end 刷脸开门配置程序专用==========================================
}
